import { useRef, useEffect } from "react";

import styled from "styled-components";

const CanvasDiv = styled.div`
  canvas {
    display: block;
    background: radial-gradient(#fff, #9cd9fa);
  }
`;
const Bg = () => {
  let canvasRef = useRef();
  let width = window.innerWidth;
  let height = window.innerHeight;
  let particles = []; //存放粒子数组
  // 粒子
  class Particle {
    constructor() {
      //大圆信息
      const cx = width / 2;
      const cy = height / 2;
      const r = Math.min(width, height) / 2;
      const rad = (getRandom(0, 360) * Math.PI) / 180;
      this.x = cx + r * Math.cos(rad);
      this.y = cy + r * Math.sin(rad);
      this.size = getRandom(2 * devicePixelRatio, 7 * devicePixelRatio); //小圆大小
    }
    draw(ctx) {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
      ctx.fillStyle = "#544544d";
      ctx.fill();
    }
    moveTo(tx, ty) {
      //小圆从大圆边上移动到对应的位置
      let duration = 500; //移动的时间
      let sx = this.x,
        sy = this.y;
      let xSpeed = (tx - sx) / duration;
      let ySpeed = (ty - sy) / duration; //速度
      let startTime = Date.now();
      const _move = () => {
        //动画移动效果
        let t = Date.now() - startTime;
        this.x = sx + t * xSpeed;
        this.y = sy + t * ySpeed;
        if (t >= duration) {
          this.x = tx;
          this.y = ty;
          return;
        }
        requestAnimationFrame(_move);
      };
      _move();
    }
  }
  const getRandom = (min, max) => {
    return Math.floor(Math.random() * (max - min + 1) + min);
  };
  const clear = (ctx) => {
    ctx.clearRect(0, 0, width, height);
  };
  const getPoints = (ctx) => {
    let points = [];
    let { data } = ctx.getImageData(0, 0, width, height);
    let gap = 4;
    for (let i = 0; i < width; i += gap) {
      for (let j = 0; j < height; j += gap) {
        let index = (i + j * width) * 4; //每组的起始位置下标
        let r = data[index];
        let g = data[index + 1];
        let b = data[index + 2];
        let a = data[index + 3];
        if (r === 0 && g === 0 && b === 0 && a === 255) {
          points.push([i, j]);
        }
      }
    }
    return points;
  };
  // 获取文字内容
  const getText = () => {
    return new Date().toTimeString().substring(0, 8);
  };
  // 更新文字方法
  let text = null;
  const update = (ctx) => {
    let curText = getText();
    if (curText === text) return; //防止频发触发
    clear(ctx); //防止绘制文字重叠，清空上次的内容
    text = curText;
    ctx.fillStyle = `#000`; //黑色
    ctx.textBaseline = "middle";
    ctx.font = `${180 * devicePixelRatio}px DS-Digital`;
    ctx.textAlign = "center";
    ctx.fillText(text, width / 2, height / 2);
    let points = getPoints(ctx); //获取像素点
    clear(ctx);
    for (let i = 0; i < points.length; i++) {
      let [x, y] = points[i];
      let p = particles[i]; //查看粒子数组中是否存在该像素点
      if (!p) {
        p = new Particle();
        particles.push(p);
      }

      p.moveTo(x, y);
    }
    if (points.length < particles.length) {
      particles.splice(points.length);
    }
  };
  // 绘制方法
  const draw = (ctx) => {
    clear(ctx); //清除上一次绘制的内容
    update(ctx);
    for (let p of particles) {
      p.draw(ctx);
    }
    requestAnimationFrame(() => draw(ctx)); //确保参数不会丢失
  };
  useEffect(() => {
    let canvas = canvasRef.current;
    canvas.width = width;
    canvas.height = height;
    let ctx = canvas.getContext("2d", { willReadFrequently: true });
    draw(ctx);
  }, []);
  return (
    <CanvasDiv>
      <canvas ref={canvasRef}></canvas>
    </CanvasDiv>
  );
};

export default Bg;
